#include "sim_i2c.h"
#include "los_task.h"

void _delay_us(uint32_t nus)
{
	// uint32_t i_counter = 0;
	// while(nus--)
	// {
	// 	i_counter = 9000;
	// 	while(i_counter--);
	// }
	LOS_TaskDelay(nus);
}
//初始化IIC
void USR_IIC_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	__HAL_RCC_GPIOH_CLK_ENABLE();

	GPIO_InitStructure.Pin = GPIO_PIN_7|GPIO_PIN_8;
	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
	GPIO_InitStructure.Pull = GPIO_NOPULL;
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
	HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);

	I2C_SCL_H;
	I2C_SDA_H;
}

//产生IIC起始信号
void USR_IIC_Start(void)
{
	I2C_SDA_OUT();     //sda线输出
	I2C_SDA_H;
	I2C_SCL_H;
	_delay_us(4);
	I2C_SDA_L;//START:when CLK is high,DATA change form high to low
 	_delay_us(4);
 	I2C_SCL_L;//钳住I2C总线，准备发送或接收数据
}

//产生IIC停止信号
void USR_IIC_Stop(void)
{
	I2C_SDA_OUT();//sda线输出
	I2C_SCL_L;
	I2C_SDA_L;//STOP:when CLK is high DATA change form low to high
	_delay_us(4);
	I2C_SCL_H;
	I2C_SDA_H;//发送I2C总线结束信号
	_delay_us(4);
}

//等待应答信号到来
//返回值：1，接收应答失败
//0，接收应答成功
uint8_t USR_IIC_Wait_Ack(void)
{
	uint8_t ucErrTime=0;

	I2C_SDA_IN();      //SDA设置为输入
	_delay_us(1);
	I2C_SCL_H;
	_delay_us(1);
	while(HAL_GPIO_ReadPin(I2C_SDA_PORT, I2C_SDA_PIN) == GPIO_PIN_SET)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			USR_IIC_Stop();
			return 1;
		}
	}
	I2C_SCL_L;//时钟输出0
	return 0;
}
//产生ACK应答
void USR_IIC_Ack(void)
{
	I2C_SCL_L;
	I2C_SDA_OUT();
	I2C_SDA_L;
	_delay_us(2);
	I2C_SCL_H;
	_delay_us(2);
	I2C_SCL_L;
}
//不产生ACK应答
void USR_IIC_NAck(void)
{
	I2C_SCL_L;
	I2C_SDA_OUT();
	I2C_SDA_H;
	_delay_us(2);
	I2C_SCL_H;
	_delay_us(2);
	I2C_SCL_L;
}
//IIC发送一个字节
//返回从机有无应答
//1，有应答
//0，无应答
uint8_t USR_IIC_Send_Byte(uint8_t txd,uint8_t ack)
{
	uint8_t t;

	I2C_SDA_OUT();
	I2C_SCL_L;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {
    	if((txd&0x80)>>7)
    		I2C_SDA_H;
    	else
    		I2C_SDA_L;
        txd<<=1;
        _delay_us(2);   //
        I2C_SCL_H;
		_delay_us(2);
		I2C_SCL_L;
		_delay_us(2);
    }
    if (ack)
    	return(USR_IIC_Wait_Ack());//等待nACK
    return 0;
}
//读1个字节，ack=1时，发送ACK，ack=0，发送nACK
uint8_t USR_IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;

	I2C_SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++)
	{
    	I2C_SCL_L;
    	_delay_us(2);
    	I2C_SCL_H;
        receive<<=1;
        if(HAL_GPIO_ReadPin(I2C_SDA_PORT, I2C_SDA_PIN) == GPIO_PIN_SET)
        	receive++;
        _delay_us(1);
    }
    if (!ack)
    	USR_IIC_NAck();//发送nACK
    else
        USR_IIC_Ack(); //发送ACK
    return receive;
}
